﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace PwManager
{
    /************************************
     * 加密解密类
     * 包括对称密匙和MD5
     * 默认key为 freedomF
     * **********************/
    public class EncryptHelper
    {
        public static string my_Key { get; } = "dongtian";

        #region {解密}
        /// <summary>
        /// 解密
        /// 密匙为 my_key
        /// </summary>
        /// <param name="encrypted">加密过的字节数组</param>
        /// <returns></returns>
        public static byte[] Decrypt(byte[] encrypted)
        {
            byte[] key = System.Text.Encoding.Default.GetBytes("freedomF");
            return Decrypt(encrypted, key);
        }

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="encrypted">加密过的字节数组</param>
        /// <param name="key">密匙的字节数组</param>
        /// <returns></returns>
        public static byte[] Decrypt(byte[] encrypted, byte[] key)
        {
            TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
            des.Key = Make_MD5(key);
            des.Mode = CipherMode.ECB;
            return des.CreateDecryptor().TransformFinalBlock(encrypted, 0, encrypted.Length);
        }

        #endregion

        #region {加密}
        /// <summary>
        /// 加密
        /// 使用 my_key 作为密匙
        /// </summary>
        /// <param name="original">要加密的字节数组</param>
        /// <returns></returns>
        public static byte[] Encrypt(byte[] original)
        {
            byte[] key = System.Text.Encoding.Default.GetBytes("freedomF");
            return Encrypt(original, key);
        }
        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="original">要加密的字节数组</param>
        /// <param name="key">密匙的字节数组</param>
        /// <returns></returns>
        public static byte[] Encrypt(byte[] original, byte[] key)
        {
            TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
            des.Key = Make_MD5(key);
            des.Mode = CipherMode.ECB;
            return des.CreateEncryptor().TransformFinalBlock(original, 0, original.Length);
        }
        #endregion

        public static byte[] Make_MD5(byte[] original)
        {
            MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
            byte[] keyhash = hashmd5.ComputeHash(original);
            hashmd5 = null;
            return keyhash;
        }

        #region {加密解密}
        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="original">加密过的字符串</param>
        /// <param name="key">密匙字符串</param>
        /// <returns></returns>
        public static string Decrypt(string original, string key = "dongtian")
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            byte[] inputByteArray = new byte[original.Length / 2];
            for (int x = 0; x < original.Length / 2; x++)
            {
                int i = (Convert.ToInt32(original.Substring(x * 2, 2), 16));
                inputByteArray[x] = (byte)i;
            }
            des.Key = ASCIIEncoding.ASCII.GetBytes(key);
            des.IV = ASCIIEncoding.ASCII.GetBytes(key);
            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();
            return System.Text.Encoding.Default.GetString(ms.ToArray());
        }

        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="str">要加密的字符串</param>
        /// <param name="key">密匙的字符串</param>
        /// <returns></returns>
        public static string Encrypt(string str, string key = "dongtian")
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            byte[] inputByteArray = Encoding.Default.GetBytes(str);
            des.Key = ASCIIEncoding.ASCII.GetBytes(key);
            des.IV = ASCIIEncoding.ASCII.GetBytes(key);
            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();
            var sb = new StringBuilder();
            foreach (byte b in ms.ToArray())
                sb.AppendFormat("{0:X2}", b);
            return sb.ToString();
        }
        #endregion


        #region {MD5加密}
        public static string MD5_Encrypt(string clearText)
        {
            string encryptedText = "";
            MD5_Encrypt(clearText, ref encryptedText);
            return encryptedText;
        }
        public static void MD5_Encrypt(string clearText, ref string encryptedText)
        {
            encryptedText = "";
            try
            {
                if (clearText == null)
                {
                    clearText = "";
                }
                MD5CryptoServiceProvider o_MD5 = new MD5CryptoServiceProvider();
                byte[] bytesEncrypt = System.Text.Encoding.Default.GetBytes(clearText);
                byte[] bytesEncrypted = o_MD5.ComputeHash(bytesEncrypt, 0, bytesEncrypt.Length);
                for (int i = 0; i < bytesEncrypted.Length; i++)
                {
                    encryptedText += bytesEncrypted[i].ToString("x").PadLeft(2, '0');
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        #endregion
    }
}
